var _ = console.log

var url = require("url");
var fs = require("fs");
const mime = require('mime');
const path = require('path');
const { createProxyMiddleware } = require('http-proxy-middleware');

var config = function(){
	var p = process.argv.length>=3?path.resolve(process.argv[2]):__dirname;
	if(p[p.length-1] != '/')p += '/';
	return {
		path:p,
		port:process.argv.length >= 4?process.argv[3]:80,				//ws监听端口
		suffix:['.vue','.js'],
	}
}();

var onws = function(){
	return new Promise(ok=>{
		var lis = [];
		var http = require('http');
		var websocket = require('ws');

		var server = http.createServer(async function(req,res){
			res.setHeader("Access-Control-Allow-Origin","*");
			res.setHeader("Access-Control-Allow-Headers","content-type");
			res.setHeader("Access-Control-Allow-Methods","DELETE,PUT,POST,GET,OPTIONS");
			if (req.method.toLowerCase() == 'options'){
				res.send(200);
				res.end();
				return;
			}
			
			if(typeof req.headers.toorigin === 'string'){
				createProxyMiddleware({target:req.headers.toorigin, changeOrigin: true})(req,res)
				return
			}
			var url_obj = url.parse(req.url);
			var req_path = url_obj.pathname;
			var filepath = config.path + (req_path[req_path.length-1] === '/'?req_path + 'index.html':req_path);
			var is_import = false;
			if(filepath.substr(-7) === '.import'){
				is_import = true
				filepath = filepath.substr(0,filepath.length-7)
			}
			
			fs.exists(filepath, function(exists){
				if(exists){
					fs.stat(filepath, function(err, stats){
						if(err){
							res.writeHead(500, {'Content-Type' : 'text/html;charset=utf8'});
							res.end('<div styel="color:black;font-size:22px;">server error</div>');
						}else{
							if(stats.isFile()){
								var file = fs.createReadStream(filepath);
								res.writeHead(200, {'Content-Type' : mime.getType(filepath)});
								if(is_import){
									var str = '';
									file.on('data',chunk=>{
										str += chunk
									});
									file.on('end',()=>{
										res.end(decodeURIComponent(url_obj.query.split('&')[0].split('=')[1])+'("'+str.split('\\').join('\\\\').split('\r\n').join('\\n').split('\n').join('\\n').split('"').join('\\"')+'")');
									});
								}else{
									file.pipe(res);
								}
							}else{
								res.writeHead(404, {'Content-Type' : 'text/html;charset=utf8'});
								res.end('<div styel="color:black;font-size:22px;">404 not found</div>');
							}
						}
					});
				}else{
					if(req_path === '/' || ['vue','js','png','jpg','gif','txt','tff','woff'].indexOf(req_path.split('.').pop().toLowerCase()) !== -1){
						res.writeHead(404, {'Content-Type' : 'text/html;charset=utf8'});
						res.end('<div styel="color:black;font-size:22px;">404 not found</div>');
					}else{
						var file = fs.createReadStream(config.path + '/index.html');
						res.writeHead(200, {'Content-Type' : mime.getType(req_path)});
						file.pipe(res);
					}
				}
			});
		});
		server.on('error', function(err) {
			if(err.code === 'EADDRINUSE'){
				server.listen(++config.port);
			}
		})
		server.listen(config.port,'0.0.0.0');

		server.on('listening',function(){
			const wss = new websocket.Server({ server });
			
			wss.on('connection', function connection(ws,req){
				lis.push(ws);
				ws.onclose = function(){
					var i = lis.indexOf(ws);
					if(i !== -1){
						lis.splice(i,1)
					}
				}
			});
			ok(function(msg){
				var str = JSON.stringify(['change',msg]);
				for(var v of lis){
					v.send(str);
				}
			})
		})
	})
}

var onfile = function(fn){
	var f = function(filename){
		var s = false;
		for(var v of config.suffix){
			if(filename.lastIndexOf(v) === filename.length-v.length){
				s = true;
				break;
			}
		}
		if(s){
			fn(filename.substr(config.path.length-1));
		}	
	}
	if(require('os').type() === 'Linux'){
		var chokidar = require('chokidar');

		chokidar.watch(config.path,{ignoreInitial:true}).on('change',(filename)=>{
			f(filename);
		})
	}else{
		require('fs').watch(config.path,{recursive:true},(event, filename)=>{
			if(!filename)return;
			switch(event){
				case 'change':
					f(config.path+filename.split('\\').join('/'));				
				break;
			}
		})
	}
}

!(async function(){

	var send = await onws(function(){
		
	});

	onfile(function(f){
			_(f)
		send(f)
	})

	_('start:'+config.port)

})()